﻿using System;
using System.IO;
using System.Threading;

namespace Seagull.Generic
{
    public static class FileHelper
    {
        public static FileStream Open(Func<FileStream> opener)
        {
            FileStream fileStream = null;
            Retry(() => { fileStream = opener(); });
            return fileStream;
        }

        public static void DeleteDirectory(string path)
        {
            Retry(() => Directory.Delete(path, true));
        }

        public static void CreateDirectory(string path)
        {
            Retry(() => Directory.CreateDirectory(path));
        }

        public static void MoveDirectory(string sourcePath, string destPath)
        {
            Retry(() => Directory.Move(sourcePath, destPath));
        }

        public static void Retry(Action action)
        {
            var retry = 0;
            while(true)
            {
                try
                {
                    action();
                    return;
                }
                catch (FileNotFoundException)
                {
                    throw;
                }
                catch (DirectoryNotFoundException)
                {
                    throw;
                }
                catch (IOException)
                {
                    if (++retry > 4)
                    {
                        throw;
                    }
                    Thread.Sleep(100);
                }
            }
        }

        public static bool AtEnd(this Stream stream)
        {
            return stream.Position == stream.Length;
        }
    }
}
